float4 LightColor;
float  LightIntensity;
float3 LightDirection;

float3 CameraPosition;
float3 FrustumCorners[8];
float  FarPlane;

float2 HalfPixel;

texture Normal;
sampler normalSampler = sampler_state
{
    Texture = <Normal>;
    AddressU = Clamp;
    AddressV = Clamp;
    MagFilter = Point;
    MinFilter = Point;
    Mipfilter = Point;
};

texture Depth;
sampler depthSampler = sampler_state
{
    Texture = <Depth>;
    AddressU = Clamp;
    AddressV = Clamp;
    MagFilter = Point;
    MinFilter = Point;
    Mipfilter = Point;
};

texture Color;
sampler colorSampler = sampler_state
{
    Texture = <Color>;
    AddressU = Clamp;
    AddressV = Clamp;
    MagFilter = Point;
    MinFilter = Point;
    Mipfilter = Point;
};

struct VertexShaderInput
{
    float4 Position : POSITION0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float4 Screen   : TEXCOORD0;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    output.Position = input.Position;
    output.Screen = output.Position;

    return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
    input.Screen.xy /= input.Screen.w;
    float2 texCoord = float2(input.Screen.x, -input.Screen.y) * 0.5 + 0.5;
    texCoord += HalfPixel;

    float depth = tex2D(depthSampler, texCoord);
    clip(0.99f - depth);

    // TODO: Optimize the lerps
    float3 position = lerp(
                          lerp(
                              lerp(FrustumCorners[0], FrustumCorners[1], texCoord.x),
                              lerp(FrustumCorners[3], FrustumCorners[2], texCoord.x),
                              texCoord.y),
                          lerp(
                              lerp(FrustumCorners[4], FrustumCorners[5], texCoord.x),
                              lerp(FrustumCorners[7], FrustumCorners[6], texCoord.x),
                              texCoord.y),
                          depth);

    float4 normal = tex2D(normalSampler, texCoord);
    normal.xyz = normal.xyz * 2 - 1;

    // Compute diffuse color
    float diffuseLight = dot(-normal, normalize(LightDirection));
    //clip(diffuseLight);
    
    float3 reflectionVector = normalize(reflect(-LightDirection, normal));
    float3 cameraVector = normalize(position - CameraPosition);
    float4 color = tex2D(colorSampler, texCoord);

    // Compute specular color
    float specularLight = saturate(dot(reflectionVector, cameraVector));
    float specularIntensity = normal.a;
    float specularPower = color.a;

    float4 output;
    output.rgb = LightColor.rgb * LightIntensity * diffuseLight;
    output.a = 1;//LightIntensity * specularIntensity * pow(specularLight, specularPower);

    return output;
}

technique Technique1
{
    pass Pass1
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
